package com.ijiuchuang.jc_localization.rx;

import android.support.annotation.NonNull;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

import rx.Observable;
import rx.subjects.PublishSubject;
import rx.subjects.Subject;

/**
 * Created by Veev on 2016/6/20
 *
 * @link 384506557@qq.com
 */
public class RxBus {

    private static final String DEFAULT_TAG = "rxBus.tag.DEFAULT_TAG";

    private static volatile RxBus sInst = null;
    public static RxBus getInstance() {
        RxBus inst = sInst;
        if (inst == null) {
            synchronized (RxBus.class) {
                inst = sInst;
                if (inst == null) {
                    inst = new RxBus();
                    sInst = inst;
                }
            }
        }
        return inst;
    }

    private RxBus() {}

    private ConcurrentHashMap<String, List<Subject>> subjectMapper = new ConcurrentHashMap<>();

    public <T> Observable<T> register (Object object) {
        return this.register(DEFAULT_TAG, object);
    }

    @SuppressWarnings("unchecked")
    public <T> Observable<T> register (@NonNull String tag, @NonNull Object object) {
        List<Subject> subjectList;
        if (subjectMapper.containsKey(tag)) {
            subjectList = subjectMapper.get(tag);
        } else {
            subjectList = new ArrayList<>();
            subjectMapper.put(tag, subjectList);
        }

        Subject<T, T> subject = PublishSubject.create();
        subjectList.add(subject);

        return subject;
    }

    public void unregister(Observable observable) {
        this.unregister(DEFAULT_TAG, observable);
    }

    public void unregister(@NonNull String tag, @NonNull Observable observable) {
        if (subjectMapper.containsKey(tag)) {
            List<Subject> subjectList = subjectMapper.get(tag);
            subjectList.remove((Subject) observable);
            if (subjectList.isEmpty()) {
                subjectMapper.remove(tag);
            }
        }
    }

    public void post(Object content) {
        this.post(DEFAULT_TAG, content);
    }

    @SuppressWarnings("unchecked")
    public void post(@NonNull String tag, @NonNull Object content) {
        if (subjectMapper.containsKey(tag)) {
            List<Subject> subjectList = subjectMapper.get(tag);
            if (subjectList == null) {
                return;
            }
            for (Subject subject : subjectList) {
                if (subject != null) {
                    subject.onNext(content);
                }
            }
        }
    }
}
